/**
 * 数据类型
 * @author  姚格格
 * @date    2020-05-28 21:09
 *
 * 布尔值 /数字 / 字符串 / 数组 / 元祖tuple /联合类型 / 枚举 / any / void / null / undefined / never / object({},[]) / 类型断言
 *
 */


let married: boolean = false;
let age: number = 12;

let name: string = 'zhangsan';

//di定义数组的方式  数组里面的数据类型唯一，数量不确定
let arr1: number[] = [1, 2, 3];
let arr2: Array<number> = [1, 3, 4];

//元祖类型：tuple  表示一个已知数量和类型的数组
let zhufeng: [string, number] = ['ygg', 1];


//普通枚举类型
enum Gender {
    MALE,
    FEMALE
}

//不普通枚举，常量枚举
const enum Colors {
    RED,
    GREEN,
    BLACK
}


//any 可以赋值给任意类型

let root: HTMLElement | null = document.getElementById('root');

//  !  非空断言    表示告诉ts我确定root不为空，所以无需判断
root!.style.color = 'red';


//null undefined  是其他类型的子类型，可以赋值给其他类型，比如说数字类型
let x: number;
x = 1;

//strictNullChecks   为true  null值的严格检查 就不能把undefined null 赋值给x   设置为false就可以赋给number

x = undefined;
x = null;


//void 表示没有任何类型
function greet(name: string): void {
    return undefined;
    // return null   :null  不支持
}

//never：永远不会出现的值  其他所有类型的子类型


function error(mes: string): never {
    throw new Error(mes)
}


//never和void的区别：
// 1.void可以赋值为null  undefined，但是never不包含任何值
// 2.定义void 返回值类型的函数能够正常运行，但是拥有never返回值的函数永远无法返回，无法终止


//包装对象：wrapper object
//js的数据类型：原始数据类型：number，string，boolean，null undefined， symbol， ：对象类型，引用类型
//  原始类型是没有属性和方法的，当你在调用基本类型的方法的时候，js会迅速对原始类型进行包装成对象，调用的是对象上的方法。
let name2 = 'zhufeng';
console.log(name2.toUpperCase());

//相当于：new String(name1).toUpperCase();

//联合类型：
let name3: string | number;
name3 = '111'
name3.toUpperCase();
name3 = 2
name.toUpperCase()


//类型断言  ：在单元测试中   可以把一个联合的变量可以指定为一个更加具体的类型
let name1: string | number;
(name1 as string).length;
(name1 as number).toFixed();


//字面量类型：  可以把字符串，数字，布尔值，字面量组成一个联合类型   ：type是自定义的一个类型
type myType = 1 | 'yes' | true;

let t1: myType = 1;
let t2: myType = 'yes';
let t3: myType = true;

//字面量是值的联合，联合是类型的联合

//可索引类型  支持【number/string】两种索引签名
interface StringArray {
    [index: number]: string
}

let myArray: StringArray = ['bob', 'fred'];
let myStr: string = myArray[0];

//两种数字签名可以同时使用，但是数字索引的返回值必须是字符串索引的子类型

class Animal {
    name: string
}

class Dog extends Animal {
    breed: string
}

interface NotOkay {
    [x: number]: Dog
    //number类型的Dog是animal的子类型，
    [x: string]: Animal
}


//如果一个ts文件里面有export或者import语句，ts会把他当成一个模块处理，ts会把他当成一个模块处理，里面的变量都是私有变量，不会出现命名冲突，如果没有export或者import语句，那当前文件就是全局
export {}


